package com.t.bricks.bussiness.db.dao.tablekey.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.t.bricks.bussiness.db.dao.tablekey.TableKeyDao;
import com.t.bricks.bussiness.db.entity.tablekey.TableKey;
import com.t.bricks.bussiness.db.mapper.tablekey.TableKeyMapper;
import com.t.bricks.model.Log;
import com.t.bricks.model.MsgEmity;

@Repository
public class TableKeyDaoImpl implements TableKeyDao<TableKey> {
	
	@Autowired
	private TableKeyMapper tableKeyMapper;

	/**
	 * 序列锁集合
	 */
	private static Map<String, Object> mapLock = new ConcurrentHashMap<String, Object>(5);
	
	/**
	 * 序列锁引用计数值集合,当值为0时同时清理'序列锁集合'
	 */
	private static Map<String, Integer> mapLockCount = new ConcurrentHashMap<String, Integer>(5);

	/**
	 * 添加
	 * @param tableKey
	 * @return
	 */
	@Override
	public MsgEmity add(TableKey tableKey) {
		try {
			int i = tableKeyMapper.add(tableKey);
			if (i < 1) {
				Log.error("新增未能得到预期影响值(预期1):", i);
				return new MsgEmity(false, "新增数据失败！", 7001);
			}
		} catch (Exception e) {
			Log.error("新增时发生异常:", e.getMessage());
			return new MsgEmity(false, "新增失败！", 7002);
		}
		
		return new MsgEmity(true, "新增成功！", tableKey);
	}

	/**
	 * 取各表的新Id
	 * @param formatLong 格式化长度(不足长度+0)
	 * @param seriesName
	 * @return
	 */
	@Override
	public String getNewId(int formatLong, String seriesName) {
		Object lockObj = null;//锁标识
		
		synchronized (this) {
			lockObj = mapLock.get(seriesName);//获取对象锁
			if (null == lockObj) {
				lockObj = new Object();
				mapLock.put(seriesName, lockObj);
				mapLockCount.put(seriesName, 1);//计数值
			} else {
				mapLockCount.put(seriesName, mapLockCount.get(seriesName) + 1);//计数值+1
			}
		}

		String sId = null;
		synchronized (lockObj) {
			try {
				try {
					int iCount = tableKeyMapper.newValue(seriesName);
					if (iCount != 1) {
						iCount = tableKeyMapper.addTable(seriesName);
						if (iCount != 0) {
							StringBuilder sb = new StringBuilder(6).append("%0").append(formatLong).append("d");
							return String.format(sb.toString(), 1);
						}
						
						return "0";//说明是取值失败
					}
				} catch (Exception e) {
					Log.error("添加序列发生异常:", e.getMessage());
					return "0";
				}
				
				try {
					sId = tableKeyMapper.findLastId(seriesName);
				} catch (Exception e) {
					Log.error("取新编号发生异常:", e.getMessage());
					return "0";
				}
			} finally{
				mapLockCount.put(seriesName, mapLockCount.get(seriesName) - 1);//计数值-1
				if (mapLockCount.get(seriesName) < 1) {//计数值为0,剔除
					mapLockCount.remove(seriesName);
					mapLock.remove(seriesName);
				}
			}
		}
		
		int addLength = formatLong - sId.length();
		StringBuilder sb = new StringBuilder(formatLong);
		for(int i = 0; i < addLength; i++) {
			sb.append("0");
		}
		sb.append(sId);
		
		return sb.toString();
	}
	
	/**
	 * 取各表的一批新Id
	 * @param formatLong 格式化长度(不足长度+0)
	 * @param seriesName
	 * @param size 数量
	 * @return
	 */
	@Override
	public List<String> getNewIds(int formatLong, String seriesName, int size) {
		Object lockObj = null;//锁标识
		
		synchronized (this) {
			lockObj = mapLock.get(seriesName);//获取对象锁
			if (null == lockObj) {
				lockObj = new Object();
				mapLock.put(seriesName, lockObj);
				mapLockCount.put(seriesName, 1);//计数值
			} else {
				mapLockCount.put(seriesName, mapLockCount.get(seriesName) + 1);//计数值+1
			}
		}

		long vId = 0;
		try {
			synchronized (lockObj) {
				int iCount = tableKeyMapper.newValues(seriesName, size);
				if (iCount != 1) {
					iCount = tableKeyMapper.addTableValues(seriesName, size);
				}
				
				if (iCount != 1) {
					return null;//说明是取值失败
				}
				
				vId = Long.valueOf(tableKeyMapper.findLastId(seriesName));//取得最大的id,因使用代码锁,可保证不会出现冲突
			}
			
			List<String> result = new ArrayList<String>(size);
			for (int i=size -1; i > 0; i--) {
				String sId = String.valueOf(vId - i);
				
				int addLength = formatLong - sId.length();
				for(int n = 0; n < addLength; n++) {
					sId = "0" + sId;
				}
				result.add(sId);
			}
			
			return result;
		} finally{
			mapLockCount.put(seriesName, mapLockCount.get(seriesName) - 1);//计数值-1
			if (mapLockCount.get(seriesName) < 1) {//计数值为0,剔除
				mapLockCount.remove(seriesName);
				mapLock.remove(seriesName);
			}
		}
	}
	
	/**
	 * 重置
	 * @param seriesName
	 * @return
	 */
	@Override
	public String reset(String seriesName) {
		int iCount = tableKeyMapper.reset(seriesName);
		
		if (iCount < 1) {
			return "0";
		}
		
		return "1";
	}
	
}
